package cn.edu.nwpu.warehousemanagement.service.impl;

import cn.edu.nwpu.warehousemanagement.constantEnum.FreightStatus;
import cn.edu.nwpu.warehousemanagement.dao.FreightRepository;
import cn.edu.nwpu.warehousemanagement.dao.InventoryConfigRepository;
import cn.edu.nwpu.warehousemanagement.dao.ProductRepository;
import cn.edu.nwpu.warehousemanagement.pojo.Freight;
import cn.edu.nwpu.warehousemanagement.pojo.InventoryConfig;
import cn.edu.nwpu.warehousemanagement.pojo.Product;
import cn.edu.nwpu.warehousemanagement.pojo.Result;
import cn.edu.nwpu.warehousemanagement.pojo.dto.PageDTO;
import cn.edu.nwpu.warehousemanagement.pojo.dto.ProductStatisticsDTO;
import cn.edu.nwpu.warehousemanagement.service.ProductService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@RequiredArgsConstructor
@Slf4j
public class ProductServiceImpl implements ProductService {

    private final ProductRepository productRepository;
    private final FreightRepository freightRepository;
    private final InventoryConfigRepository inventoryConfigRepository;

    @Override
    @Transactional
    public Result<Product> create(Product product) {
        try {
            // 检查名称是否已存在（不包括已删除的）
            if (productRepository.existsByNameAndDeletedFalse(product.getName())) {
                return Result.error("商品名称已存在");
            }

            // 设置默认数量为0
            if (product.getQuantity() == null) {
                product.setQuantity(0L);
            }

            // 确保新建的商品未删除
            product.setDeleted(false);

            Product savedProduct = productRepository.save(product);
            return Result.success(savedProduct);
        } catch (Exception e) {
            return Result.error("创建商品失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<Void> delete(Long id) {
        try {
            Optional<Product> productOptional = productRepository.findByIdAndDeletedFalse(id);
            if (productOptional.isEmpty()) {
                return Result.error("商品不存在或已被删除");
            }

            // 检查关联的Freight记录：必须全部为SHIPPED状态
            List<Freight> activeFreights = freightRepository.findByProductIdAndStatusNotAndDeletedFalse(id, FreightStatus.SHIPPED);
            if (!activeFreights.isEmpty()) {
                return Result.error("存在未出库的货物，无法删除商品");
            }

            // 软删除Product
            Product product = productOptional.get();
            product.setDeleted(true);
            productRepository.save(product);

            // 级联软删除关联的InventoryConfig
            Optional<InventoryConfig> configOptional = inventoryConfigRepository.findByProductIdAndDeletedFalse(id);
            configOptional.ifPresent(config -> {
                config.setDeleted(true);
                inventoryConfigRepository.save(config);
            });

            return Result.success();
        } catch (Exception e) {
            return Result.error("删除商品失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<Product> update(Product product) {
        try {
            if (product.getId() == null) {
                return Result.error("ID不能为空");
            }

            // 检查记录是否存在且未删除
            Optional<Product> existingProduct = productRepository.findByIdAndDeletedFalse(product.getId());
            if (existingProduct.isEmpty()) {
                return Result.error("商品不存在或已被删除");
            }

            // 检查名称是否与其他未删除的商品冲突
            if (productRepository.existsByNameAndIdNotAndDeletedFalse(product.getName(), product.getId())) {
                return Result.error("商品名称已存在");
            }

            // 更新记录
            Product updatedProduct = productRepository.save(product);
            return Result.success(updatedProduct);
        } catch (Exception e) {
            return Result.error("更新商品失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Product> getById(Long id) {
        try {
            Optional<Product> product = productRepository.findByIdAndDeletedFalse(id);
            return product.map(Result::success)
                    .orElseGet(() -> Result.error("商品不存在或已被删除"));
        } catch (Exception e) {
            return Result.error("查询商品失败: " + e.getMessage());
        }
    }

    @Override
    public Result<List<Product>> getByName(String name) {
        try {
            List<Product> products = productRepository.findByNameContainingAndDeletedFalse(name);
            if (products.isEmpty()) {
                return Result.error("未找到匹配的商品");
            }
            return Result.success(products);
        } catch (Exception e) {
            return Result.error("根据名称查询商品失败: " + e.getMessage());
        }
    }

    @Override
    public Result<Page<Product>> listByPage(PageDTO pageDTO) {
        try {
            // 页码从0开始，每页20条
            Pageable pageable = PageRequest.of(pageDTO.getPageNum() - 1, pageDTO.getPageSize());
            Page<Product> page = productRepository.findByDeletedFalse(pageable);
            return Result.success(page);
        } catch (Exception e) {
            return Result.error("分页查询商品失败: " + e.getMessage());
        }
    }

    @Override
    public Result<List<Page<Product>>> getAllProductPages() {
        try {
            List<Page<Product>> allPages = new ArrayList<>();
            int pageNum = 1;
            boolean hasMore = true;

            // 循环获取所有页
            while (hasMore) {
                Pageable pageable = PageRequest.of(pageNum - 1, 20);
                Page<Product> page = productRepository.findByDeletedFalse(pageable);
                allPages.add(page);

                // 检查是否还有下一页
                if (pageNum >= page.getTotalPages()) {
                    hasMore = false;
                }
                pageNum++;
            }

            return Result.success(allPages);
        } catch (Exception e) {
            return Result.error("获取所有商品分页失败: " + e.getMessage());
        }
    }

    @Override
    public Result<List<Product>> getAllProductList() {
        try {
            List<Product> allProducts = new ArrayList<>();
            int pageNum = 1;
            boolean hasMore = true;

            // 循环获取所有页并合并结果
            while (hasMore) {
                Pageable pageable = PageRequest.of(pageNum - 1, 20);
                Page<Product> page = productRepository.findByDeletedFalse(pageable);
                allProducts.addAll(page.getContent());

                // 检查是否还有下一页
                if (pageNum >= page.getTotalPages()) {
                    hasMore = false;
                }
                pageNum++;
            }

            return Result.success(allProducts);
        } catch (Exception e) {
            return Result.error("获取所有商品列表失败: " + e.getMessage());
        }
    }



    @Override
    @Transactional(readOnly = true)
    public Result<ProductStatisticsDTO> getProductStatistics() {
        long startTime = System.currentTimeMillis();

        try {
            ProductStatisticsDTO stats = new ProductStatisticsDTO();

            // 1. 顺序获取基础统计信息
            long productCount = productRepository.countByDeletedFalse();
            long usedShelfCount = productRepository.countUsedShelves();

            // 2. 一次性获取所有产品统计信息
            List<Object[]> statsData = productRepository.findAllFreightStats();

            // 3. 处理统计结果
            List<ProductStatisticsDTO.ProductFreightStats> freightStatsList = new ArrayList<>();

            for (Object[] row : statsData) {
                Long productId = ((Number) row[0]).longValue();
                String productName = (String) row[1];
                Long shippedCount = ((Number) row[2]).longValue();
                Long inStockCount = ((Number) row[3]).longValue();

                freightStatsList.add(new ProductStatisticsDTO.ProductFreightStats(
                        productId, productName, shippedCount, inStockCount
                ));
            }

            // 4. 设置统计结果
            stats.setProductCount(productCount);
            stats.setUsedShelfCount(usedShelfCount);
            stats.setFreightStats(freightStatsList);

            long duration = System.currentTimeMillis() - startTime;
            log.info("产品统计完成，产品种类: {}, 耗时: {}ms", productCount, duration);

            return Result.success(stats);
        } catch (Exception e) {
            log.error("获取产品统计信息失败", e);
            return Result.error("获取产品统计信息失败: " + e.getMessage());
        }
    }

//    // 添加缓存版本（可选）
//    // @Cacheable(value = "productStatistics", key = "'all'")
//    public Result<ProductStatisticsDTO> getCachedProductStatistics() {
//        return getProductStatistics();
//    }
}